/*
 * Copyright (c) 2023-2025 110476592@qq.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file abs_painter.h
 * @brief 截图工具 
 * @author 110476592@qq.com 
 * @note   承接Qt项目外包定制开发。长期接收C++项目实训学徒,联系QQ：110476592。
 */

 
#ifndef ABS_PAINTER_H
#define ABS_PAINTER_H
#include <QPainter>
#include <QVector>
#include <common/draw_context.h>


/**
   * @brief 抽象绘画器基类，继承自 QObject，使用 Qt 的信号与槽机制
   * 该类定义了绘画器的基本接口和通用功能，其他具体的绘画器类可继承此类并实现纯虚函数。
   */
class AbsPainter : public QObject {
  // 声明该类使用 Qt 的信号与槽机制
  Q_OBJECT
  
public:
  /**
   * @brief 构造函数
   * @param parent 父对象指针，默认为 nullptr
   */
  explicit AbsPainter(QObject *parent = nullptr);

  /**
   * @brief 获取绘画器的唯一标识符
   * 这是一个纯虚函数，派生类必须实现该函数以提供唯一的标识符。
   * @return 表示绘画器唯一标识符的整数
   */
  virtual int id() const = 0;

  /**
   * @brief 执行图像绘制操作
   * @param painter 用于绘制的 QPainter 对象
   * @param points 绘制所需的点的向量
   * @param param 绘制参数对象
   * @return false 表示绘画失败，应停止绘画；true 表示绘画成功
   */
  bool drawImage(QPainter &painter, const QVector<QPoint> &points,
                 const DrawParam &param);

  /**
   * @brief 开始改变绘画的不透明度
   * 调用此函数将开始改变绘画的不透明度。
   */
  void startOpactiy();

  /**
   * @brief 发送绘画结束通知
   * 该函数用于发送绘画结束的通知。
   */
  void sendEndNotify();

protected:
  /**
   * @brief 处理绘画命令
   * 派生类可以重写此函数来实现具体的绘画逻辑。
   * @param painter 用于绘制的 QPainter 对象
   * @param points 绘制所需的点的向量
   * @param param 绘制参数对象
   */
  virtual void processImage(QPainter &painter, const QVector<QPoint> &points,
                            const DrawParam &param) {
    // 标记参数未使用，避免编译器警告
    Q_UNUSED(painter);
    Q_UNUSED(points);
    Q_UNUSED(param);
  }

  /**
   * @brief 减少绘画的不透明度
   * 该函数用于减少当前绘画的不透明度。
   */
  void decOpactiy();

  /**
   * @brief 判断绘画器是否处于生命期内
   * @return true 表示在生命期内，false 表示不在生命期内
   */
  bool isLive();

public slots:
  /**
   * @brief 处理鼠标按下事件
   * 这是一个纯虚函数，派生类必须实现该函数以处理鼠标按下事件。
   */
  virtual void onPressed() = 0;

protected:
  qreal m_opacity = 1.0f; ///<  当前绘画的不透明度，初始值为 1.0f
  bool m_startOpactiy = false;  ///< 标记是否开始改变不透明度
  bool m_sendNotify = false; /// 标记是否发送绘画结束通知
};


/**
 * @brief 宏定义，用于向绘画器工厂注册特定类型的绘画器
 *
 * 该宏会创建一个静态对象，在程序启动时自动将指定类型的绘画器注册到绘画器工厂中。
 *
 * @param painterType 要注册的绘画器的类型，通常是一个枚举值
 * @param PainterName 具体绘画器类的名称，该类应继承自 AbsPainter
 */
#define REGISTER_PAINTER(painterType,PainterName) \
\
    class Painter##PainterName{ \
      public: \
      Painter##PainterName(){ \
        PainterFactory::getInstance().registerPainter(painterType,new PainterName());\
  } \
 \
};\
Painter##PainterName __g_##PainterName##_register_;
#endif
